package com.yz.jdd.widget.keyboard;

import android.app.Activity;
import android.content.Context;
import android.inputmethodservice.Keyboard;
import android.inputmethodservice.KeyboardView;
import android.os.Build;
import android.text.Editable;
import android.text.InputType;
import android.text.TextUtils;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;


import com.yz.jdd.R;
import com.yz.jdd.base.utils.LogUtils;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Random;

/**
 * 自定义键盘
 */
public class KeyboardUtil {

    public static final int CLEAR_CODE = 4896;//清除code
    public static final int ADD_CODE = 4897;//+号code
    private final int BTN_1 = -411;
    private final int BTN_2 = -412;
    private static final String CHAR_POINT = ".";
    private static final String CHAR_ADD = "+";
    private double maxValue = 999999.991;//最大限制
    TextView inputRecords;

    private Activity mActivity;
    private boolean mIfRandom;

    private MyKeyBoardView mKeyboardView;
    private Keyboard mKeyboardNumber;//数字键盘
    private EditText mEditText;
    private int xmlIds;
    private List<String> listPermission;
    private boolean haveScan;//是否有扫码付款
    private boolean isHideKeyboard = true;
    String expression = "";//记录表达式


    public KeyboardUtil(Activity activity, int xmlIds, String okStr, String clearStr) {
        this(activity, false, xmlIds, okStr, clearStr, null, true);
    }

    public KeyboardUtil(Activity activity, int xmlIds, String okStr, String clearStr, List<String> listPermission, boolean haveScan) {
        this(activity, false, xmlIds, okStr, clearStr, listPermission, haveScan);
    }

    public KeyboardUtil(Activity activity, boolean ifRandom, int xmlIds, String okStr, String clearStr, List<String> listPermission, boolean haveScan) {
        this.xmlIds = xmlIds;
        this.mActivity = activity;
        this.mIfRandom = ifRandom;
        this.listPermission = listPermission;
        this.haveScan = haveScan;
        mKeyboardNumber = new Keyboard(mActivity, xmlIds);
        mKeyboardView = (MyKeyBoardView) mActivity.findViewById(R.id.keyboard_view);
        mKeyboardView.setOkButton(okStr);
        mKeyboardView.setClearButton(clearStr);
    }

    public void setPayTypeButton(String btnStr1, String btnStr2) {
        mKeyboardView.setPayTypeButton(btnStr1, btnStr2);
    }

    public int getkeyHeigth() {
        return mKeyboardView.getkeyHeigth();
    }

    /**
     * edittext绑定自定义键盘
     *
     * @param editText 需要绑定自定义键盘的edittext
     */
    public void attachTo(EditText editText) {
        this.mEditText = editText;
        hideSystemSofeKeyboard(mActivity.getApplicationContext(), mEditText);
        showSoftKeyboard();
    }

    public void setExpression(String expression){
        this.expression = expression;
    }

    /**
     * edittext绑定自定义键盘
     *
     * @param textView 展示计算过程
     * @param editText 需要绑定自定义键盘的edittext
     */
    public void attachTo(TextView textView, EditText editText) {
        this.inputRecords = textView;
        this.mEditText = editText;
        hideSystemSofeKeyboard(mActivity.getApplicationContext(), mEditText);
        showSoftKeyboard();
    }

    public void setOkButtonColor(int buttonNormalColor, int buttonPressedColor, int textColor) {
        mKeyboardView.setOkButtonColor(buttonNormalColor, buttonPressedColor, textColor);
    }

    public void showSoftKeyboard() {
        if (mKeyboardNumber == null) {
            mKeyboardNumber = new Keyboard(mActivity, xmlIds);
        }
        if (mKeyboardView == null) {
            mKeyboardView = (MyKeyBoardView) mActivity.findViewById(R.id.keyboard_view);
        }
        if (mIfRandom) {
            randomKeyboardNumber();
        } else {
            mKeyboardView.setKeyboard(mKeyboardNumber);
        }
        mKeyboardView.setEnabled(true);
        mKeyboardView.setPreviewEnabled(false);
        mKeyboardView.setVisibility(View.VISIBLE);
        mKeyboardView.setOnKeyboardActionListener(mOnKeyboardActionListener);

    }

    private KeyboardView.OnKeyboardActionListener mOnKeyboardActionListener = new KeyboardView.OnKeyboardActionListener() {
        @Override
        public void onPress(int primaryCode) {

        }

        @Override
        public void onRelease(int primaryCode) {

        }

        @Override
        public void onKey(int primaryCode, int[] keyCodes) {
            if (inputRecords == null) {
                onKeyNormal(primaryCode, keyCodes);
            } else {
                onKeyAdd(primaryCode, keyCodes);
            }
        }

        @Override
        public void onText(CharSequence text) {
        }

        @Override
        public void swipeLeft() {

        }

        @Override
        public void swipeRight() {

        }

        @Override
        public void swipeDown() {

        }

        @Override
        public void swipeUp() {

        }
    };

    /**
     * 正常键盘
     *
     * @param primaryCode
     * @param keyCodes
     */
    private void onKeyNormal(int primaryCode, int[] keyCodes) {
        Editable editable = mEditText.getText();
        int start = mEditText.getSelectionStart();
        String value = Character.toString((char) primaryCode);
        if (primaryCode == Keyboard.KEYCODE_DELETE) {// 回退
            if (editable != null && editable.length() > 0) {
                if (start > 0) {
                    editable.delete(start - 1, start);
                }
            }
        } else if (primaryCode == Keyboard.KEYCODE_CANCEL) {
            keyCodeCancle();
        } else if (primaryCode == Keyboard.KEYCODE_DONE) {
            //确认 或 收款键
            keyCodeDone();
        } else if (primaryCode == CLEAR_CODE) {
//            if (editable != null && editable.length() > 0) {
//                //清空键盘
//                editable.clear();
//            }
            keyCodeClear();
            if(onHideClickListener!=null){
                onHideClickListener.onHideClick();
            }

        } else if (primaryCode == BTN_1 || primaryCode == BTN_2) {
            //收银键盘 收款方式
            hideKeyboard();
            if (mOnOkClickCode != null) {
                mOnOkClickCode.OnOkClickCode(primaryCode);
            }
        } else {
            editable.insert(start, Character.toString((char) primaryCode));
        }
        if (mOnClickValue != null) {

            if (primaryCode == -5 || primaryCode == -3 || primaryCode == -4
                    || primaryCode == 4896 || primaryCode == BTN_1 || primaryCode == BTN_2) {
                value = "click";
            }
            mOnClickValue.onOkClickVal(value, mEditText);
        }
    }

    /**
     * 计算功能见键盘
     *
     * @param primaryCode
     * @param keyCodes
     */
    public void onKeyAdd(int primaryCode, int[] keyCodes) {
        if (inputRecords == null) {
            onKeyNormal(primaryCode, keyCodes);
            return;
        }
        String value = Character.toString((char) primaryCode);
        LogUtils.d("onKeyAdd:----------------->" + value);
        if (primaryCode == Keyboard.KEYCODE_DELETE) {// 回退
            keyCodeDelete(false);
        } else if (primaryCode == Keyboard.KEYCODE_CANCEL) {
            keyCodeCancle();
        } else if (primaryCode == Keyboard.KEYCODE_DONE) {
            //确认 或 收款键
            keyCodeDone();
        } else if (primaryCode == CLEAR_CODE) {
            //清空

            keyCodeClear();
            if(onHideClickListener!=null){
                onHideClickListener.onHideClick();
            }

        } else if (primaryCode == ADD_CODE) {
            keyCodeAdd();
        } else if (primaryCode == BTN_1 || primaryCode == BTN_2) {
            //收银键盘 收款方式
            hideKeyboard();
            if (mOnOkClickCode != null) {
                mOnOkClickCode.OnOkClickCode(primaryCode);
            }
        } else {
            if (keyCodeNumber(primaryCode)) {
                value = "click";
            }
        }
        if (mOnClickValue != null) {
            if (primaryCode == -5 || primaryCode == -3 || primaryCode == -4
                    || primaryCode == 4896 || primaryCode == BTN_1 || primaryCode == BTN_2) {
                value = "click";
            }
            if (primaryCode == ADD_CODE) {
                value = "add";
            }
            mOnClickValue.onOkClickVal(value, mEditText);
        }
    }

    public void keyCodeCancle() {
        hideKeyboard();
        if (mOnCancelClick != null) {
            mOnCancelClick.onCancellClick();
        }
    }

    public void keyCodeDone() {
        hideKeyboard();
        if (mOnOkClick != null) {
            mOnOkClick.onOkClick();
        }
    }

    /**
     * 隐藏系统键盘
     *
     * @param editText
     */
    public static void hideSystemSofeKeyboard(Context context, EditText editText) {
        int sdkInt = Build.VERSION.SDK_INT;
        if (sdkInt >= 11) {
            try {
                Class<EditText> cls = EditText.class;
                Method setShowSoftInputOnFocus;
                setShowSoftInputOnFocus = cls.getMethod("setShowSoftInputOnFocus", boolean.class);
                setShowSoftInputOnFocus.setAccessible(true);
                setShowSoftInputOnFocus.invoke(editText, false);

            } catch (SecurityException e) {
                e.printStackTrace();
            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            } catch (Exception e) {
                e.printStackTrace();
            }
        } else {
            editText.setInputType(InputType.TYPE_NULL);
        }
        // 如果软键盘已经显示，则隐藏
        InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
        if (imm.isActive()) {
            imm.hideSoftInputFromWindow(editText.getWindowToken(), 0);
        }
    }

    public interface OnOkClick {
        void onOkClick();
    }

    public interface OnOkClickCode {
        void OnOkClickCode(int Code);
    }

    public interface OnOkClickValue {
        void onOkClickVal(String value, EditText edit);
    }

    public interface onCancelClick {
        void onCancellClick();
    }

    public interface onAddClick {
        void onAddClick();
    }

    public interface onBackDeleteClick {
        void onBackDeleteClick();
    }
    public interface  OnHideClickListener{
       void onHideClick();
    }


    public onAddClick mOnAddClick;
    public OnOkClick mOnOkClick = null;
    public OnOkClickValue mOnClickValue;
    public OnOkClickCode mOnOkClickCode = null;
    public onCancelClick mOnCancelClick;
    public onBackDeleteClick mOnBackDeleteClick;

    public void setOnHideClickListener(OnHideClickListener onHideClickListener) {
        this.onHideClickListener = onHideClickListener;
    }

    public OnHideClickListener onHideClickListener=null;

    public void setOnAddClick(onAddClick onAddClick) {
        mOnAddClick = onAddClick;
    }

    public void setOnOkClick(OnOkClick onOkClick) {
        mOnOkClick = onOkClick;
    }

    public void setOnOkClickCode(OnOkClickCode onOkClickCode) {
        mOnOkClickCode = onOkClickCode;
    }

    public void setOnOkClickValue(OnOkClickValue onOkClickValue) {
        mOnClickValue = onOkClickValue;
    }

    public void setOnCancelClick(onCancelClick onCancelClick) {
        mOnCancelClick = onCancelClick;
    }

    public void setOnBackDeleteClick(onBackDeleteClick onBackDeleteClick) {
        mOnBackDeleteClick = onBackDeleteClick;
    }


    private boolean isNumber(String str) {
        String wordstr = "0123456789";
        return wordstr.contains(str);
    }

    private void randomKeyboardNumber() {
        List<Keyboard.Key> keyList = mKeyboardNumber.getKeys();
        // 查找出0-9的数字键
        List<Keyboard.Key> newkeyList = new ArrayList<Keyboard.Key>();
        for (int i = 0; i < keyList.size(); i++) {
            if (keyList.get(i).label != null
                    && isNumber(keyList.get(i).label.toString())) {
                newkeyList.add(keyList.get(i));
            }
        }
        // 数组长度
        int count = newkeyList.size();
        // 结果集
        List<KeyModel> resultList = new ArrayList<KeyModel>();
        // 用一个LinkedList作为中介
        LinkedList<KeyModel> temp = new LinkedList<KeyModel>();
        // 初始化temp
        for (int i = 0; i < count; i++) {
            temp.add(new KeyModel(48 + i, i + ""));
        }
        // 取数
        Random rand = new Random();
        for (int i = 0; i < count; i++) {
            int num = rand.nextInt(count - i);
            resultList.add(new KeyModel(temp.get(num).getCode(),
                    temp.get(num).getLable()));
            temp.remove(num);
        }
        for (int i = 0; i < newkeyList.size(); i++) {
            newkeyList.get(i).label = resultList.get(i).getLable();
            newkeyList.get(i).codes[0] = resultList.get(i)
                    .getCode();
        }

        mKeyboardView.setKeyboard(mKeyboardNumber);
    }

    public void showKeyboard() {
        int visibility = mKeyboardView.getVisibility();
        if (visibility == View.GONE || visibility == View.INVISIBLE) {
            mKeyboardView.setVisibility(View.VISIBLE);
        }
    }

    public void hideKeyboard() {
        if (!isHideKeyboard) {
            int visibility = mKeyboardView.getVisibility();
            if (visibility == View.VISIBLE) {
                mKeyboardView.setVisibility(View.GONE);
            }
        }
    }

    /**
     * 清空收银台和计算记录
     */
    public void keyCodeClear() {
//        Editable editable = mEditText.getText();
//        if (editable != null && editable.length() > 0) {
//            expression = "";
//            mEditText.setText("");
//            inputRecords.setText("");
//        }
//        setInputRecordsStatus();
        int visibility = mKeyboardView.getVisibility();
        if (visibility == View.VISIBLE) {
            mKeyboardView.setVisibility(View.GONE);
        }
    }


    /**
     * 回退键操作
     *
     * @param isOutKeyBoard
     */
    public void keyCodeDelete(boolean isOutKeyBoard) {
        if (mOnBackDeleteClick != null) {
            mOnBackDeleteClick.onBackDeleteClick();
        }
        int deleteCount = 1;//删除数量
        if (isOutKeyBoard) {
            //外置键盘 .倒数第二位 . 直接删除了  暂时没有+
            if (expression.contains(CHAR_POINT)) {
                int pointIndex = expression.indexOf(CHAR_POINT);
                if (pointIndex == expression.length() - 2) {
                    deleteCount = 2;
                }
            }
        }
        if (!TextUtils.isEmpty(expression) && expression.length() > 0) {
            //先判断末尾是否是+
            if (expression.endsWith(CHAR_ADD)) {
                expression = expression.substring(0, expression.length() - deleteCount);
                inputRecords.setText(expression);
                setInputRecordsStatus();
                return;
            }
            expression = expression.substring(0, expression.length() - deleteCount);
            inputRecords.setText(expression);
            if (expression.contains(CHAR_ADD)) {
                //进行计算
                calculate();
            } else {
                mEditText.setText(expression);
            }

        }
        setInputRecordsStatus();
    }

    /**
     * 普通数字按键操作
     *
     * @param primaryCode
     */
    public boolean keyCodeNumber(int primaryCode) {
        //普通点击
        String code = Character.toString((char) primaryCode);
        String totalMoney = mEditText.getText().toString();
        if (!TextUtils.isEmpty(totalMoney)) {
            if (checkInputMoney(code, totalMoney)) {
                return true;
            }
        }
        if (CHAR_POINT.equals(code)) {
            //空值 能输入 .
            if (TextUtils.isEmpty(expression)) {
                return true;
            }
            //尾号为. 不再添加
            if (expression.endsWith(CHAR_POINT)) {
                return true;
            }
            //尾号为+ 不再添加
            if (expression.endsWith(CHAR_ADD)) {
                return true;
            }
            //最后一个数字 有 . 禁止输入
            if (!expression.contains(CHAR_ADD)) {
                //无+
                if (expression.contains(CHAR_POINT)) {
                    return true;
                }
            } else {
                String[] splitAdd = expression.split("\\" + CHAR_ADD);
                if (splitAdd.length > 0) {
                    String strAddLast = splitAdd[splitAdd.length - 1];
                    if (strAddLast.contains(CHAR_POINT)) {
                        return true;
                    }
                }
            }
        }
        //小数点后限制两位
        if (expression.contains(CHAR_ADD)) {
            if (!expression.endsWith(CHAR_ADD)) {
                //结束为+
                String[] splitNums = expression.split("\\" + CHAR_ADD);
                if (splitNums.length > 0) {
                    String endNum = splitNums[splitNums.length - 1];
                    if (checkEndNumPointMoreTwo(endNum)) {
                        return true;
                    }
                }
            }
        } else {
            //没有 +
            if (checkEndNumPointMoreTwo(expression)) {
                return true;
            }
        }
        //前面为0 后面只能输入.
        if (expression.startsWith("0") && expression.length() == 1) {
            //不是 .
            if (!CHAR_POINT.equals(code)) {
                return true;
            }
        }
        expression += code;
        inputRecords.setText(expression);
        if (expression.contains(CHAR_ADD)) {
            calculate();
        } else {
            mEditText.setText(expression);
        }
        setInputRecordsStatus();
        return false;
    }


    /**
     * 加操作
     */
    public void keyCodeAdd() {
        if (mOnAddClick != null) {
            mOnAddClick.onAddClick();
        }
        if (!TextUtils.isEmpty(expression)) {
            //尾号为+ 不再添加
            if (expression.endsWith(CHAR_ADD)) {
                setInputRecordsStatus();
                return;
            }
            //如果为0不能 输入+
            if (!expression.contains(CHAR_ADD)) {
                if (expression.startsWith("0")) {
                    double expressionDouble = Double.parseDouble(expression);
                    if (expressionDouble > 0) {
                        expression = expression + CHAR_ADD;
                        inputRecords.setText(expression);
                    }
                } else {
                    expression = expression + CHAR_ADD;
                    inputRecords.setText(expression);
                }
            } else {
                expression = expression + CHAR_ADD;
                inputRecords.setText(expression);
            }
        }
        setInputRecordsStatus();
    }

    private void setInputRecordsStatus() {
        if (inputRecords != null) {
            String s = inputRecords.getText().toString();
            if (!TextUtils.isEmpty(s) && s.contains(CHAR_ADD)) {
                inputRecords.setVisibility(View.VISIBLE);
            } else {
                inputRecords.setVisibility(View.INVISIBLE);
            }
        }
    }

    private void calculate() {
        String addResult;
        String calculate_str;
        try {
            if (expression.endsWith(CHAR_ADD)) {
                calculate_str = expression.substring(0, expression.length() - 1);
            } else {
                calculate_str = expression;
            }
//            Log.e(TAG, "当前表达式：" + calculate_str);
            addResult = Calculate.calculate(calculate_str);
            double addResultDouble = Double.parseDouble(addResult);
            addResultDouble = (double) Math.round(addResultDouble * 100) / 100;
            mEditText.setText(subZeroAndDot(addResultDouble + ""));
            mEditText.setSelection(addResult.length());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 使用java正则表达式去掉多余的.与0
     *
     * @param s
     * @return
     */
    public static String subZeroAndDot(String s) {
        if (s.indexOf(".") > 0) {
            s = s.replaceAll("0+?$", "");//去掉多余的0
            s = s.replaceAll("[.]$", "");//如最后一位是.则去掉
        }
        return s;
    }

    private boolean checkInputMoney(String inputCode, String totalMoney) {
        String recordStrTem = "";
//        String recordStr = mEditInputRecords.getText().toString().trim();
        String recordStr = inputRecords.getText().toString().trim();
        if (isNumber(inputCode)) {
            //先计算拼接后的数值
            recordStrTem = recordStr + inputCode;
            try {
                recordStrTem = Calculate.calculate(recordStrTem);
            } catch (Exception e) {
                e.printStackTrace();
                recordStrTem = totalMoney;
            }
        } else {
            recordStrTem = totalMoney;
        }
        if (checkTotalMoney(recordStrTem)) {
            return true;
        }
        return false;
    }

    /**
     * 检查总额是否超过限制
     *
     * @param totalMoney
     * @return
     */
    private boolean checkTotalMoney(String totalMoney) {
        double totalMoneyDouble = Double.parseDouble(totalMoney);
        if (totalMoneyDouble >= maxValue) {
            Toast.makeText(mActivity, "订单金额已超过最大金额", Toast.LENGTH_SHORT).show();
            return true;
        }
        return false;
    }

    /**
     * 检查最后数字小数点是否超过两位
     *
     * @param endNum
     * @return
     */
    private boolean checkEndNumPointMoreTwo(String endNum) {
        if (endNum.contains(CHAR_POINT)) {
            if (endNum.endsWith(CHAR_POINT)) {
                return false;
            }
            String[] splitPoints = endNum.split("\\" + CHAR_POINT);
            if (splitPoints.length > 0 && splitPoints.length <= 2) {
                String endNumPoint = splitPoints[splitPoints.length - 1];
                //如果尾数小数点长度大于2 禁止输入
                if (endNumPoint.contains(CHAR_POINT)) {
                    return true;
                }
                if (!TextUtils.isEmpty(endNumPoint) && endNumPoint.length() >= 2) {
                    return true;
                }
            } else {
                return true;
            }
        }
        return false;
    }
}